/*

Miranda IM: the free IM client for Microsoft* Windows*

Copyright 2000-2007 Miranda ICQ/IM project, 
all portions of this codebase are copyrighted to the people 
listed in contributors.txt.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or ( at your option ) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "commonheaders.h"
#include "m_icq.h"
#include "svcTimezone.h"

namespace NServices 
{
	namespace TimeZones 
	{
		CTzManager	Manager;

		/**
		 *
		 *
		 **/
		static BOOL UpdateProtoTimezone( LPCSTR pszProto, INT bias )
		{
			INT tz = ( INT ) ( ( CHAR )DB::Setting::GetByte( pszProto, SET_CONTACT_TIMEZONE, ( BYTE )-100 ) );
			if( tz * 30 != bias )
			{
				DB::Setting::WriteByte( pszProto, SET_CONTACT_TIMEZONE, ( BYTE )( bias / 30 ) );
				return TRUE;
			}
			return FALSE;
		}

		/**
		 *
		 *
		 **/
		VOID UpdateTimezone()
		{
			PROTOCOLDESCRIPTOR **pd;
			INT ProtoCount, i;
			TIME_ZONE_INFORMATION tzi;

			ZeroMemory( &tzi, sizeof( tzi ) );
			GetTimeZoneInformation( &tzi );

			if( !CallService( MS_PROTO_ENUMPROTOCOLS, ( WPARAM )&ProtoCount, ( LPARAM )&pd ) ) {
				for( i = 0; i < ProtoCount; i++ ) {
					if( pd[i]->type == PROTOTYPE_PROTOCOL ) {

						// update local timezone as database setting
						if( UpdateProtoTimezone( pd[i]->szName, tzi.Bias ) ) {

							// update my contact information on icq server
							CallProtoService( pd[i]->szName, PS_CHANGEINFOEX, CIXT_LOCATION, NULL );
						}
					}
				}
			}
		}

		/***********************************************************************************************************
		 * services
		 ***********************************************************************************************************/

		/**
		 * This service function provides a TIME_ZONE_INFORMATION structure
		 * for the desired contact, in case the contact's timezone can be determined.
		 * 
		 * @param		wParam		- HANDLE of the contact, to retrieve timezone information from.
		 * @param		lParam		- pointer to a TIME_ZONE_INFORMATION to fill.
		 *
		 * @retval	0 - success
		 * @retval	1 - failure
		 **/
		static INT GetContactTimeZone( WPARAM wParam, LPARAM lParam )
		{
			return Manager.GetContactTimeZoneInformation( 
				( HANDLE )wParam, 
				DB::Contact::Proto( ( HANDLE )wParam ), 
				*( ( TIME_ZONE_INFORMATION* ) lParam ) );
		}

		/**
		 * This function returns the contact's local time.
		 *
		 * @param		wParam	- HANDLE of the contact, to retrieve timezone information from.
		 * @param		lParam	- pointer to a systemtime structure
		 *	
		 * return:	TRUE or FALSE
		 **/
		static INT GetContactLocalTimeService( WPARAM wParam, LPARAM lParam )
		{
			MTime	now;

			now.GetLocalTime( ( HANDLE )wParam );
			*( ( SYSTEMTIME* )lParam ) = now.SystemTime();
			return 0;
		}

		/***********************************************************************************************************
		 * initialization
		 ***********************************************************************************************************/

		/**
		 * This function initially loads the module uppon startup.
		 **/
		VOID OnModulesLoaded()
		{
			if( DB::Setting::GetByte( SET_OPT_AUTOTIMEZONE, TRUE ) )
			{
				UpdateTimezone();
			}
		}

		/**
		 * This function initially loads the module uppon startup.
		 **/
		VOID LoadModule( VOID )
		{
			Manager.GetTimeZonesFromRegistry();
			CreateServiceFunction( MS_USERINFO_TIMEZONEINFO, GetContactTimeZone );
			CreateServiceFunction( MS_USERINFO_LOCALTIME, GetContactLocalTimeService );
		}

	} /* namespace NTimezone */

} /* namespace NServices */
